package com.momoauth.common.core.filter;

import com.alibaba.fastjson2.JSON;
import com.momoauth.common.core.utils.RequestWrapper;
import com.momoauth.common.core.utils.SensitiveWord;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 敏感词过滤
 */
@Slf4j
public class SensitiveWordsFilter implements Filter {

    /**
     * 请求参数是否以静默的方式过滤敏感词
     * true：静默过滤敏感词，false：直接拒绝请求（默认）
     */
    boolean isSilent = false;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        RequestWrapper requestWrapper = new RequestWrapper(request);
        Map<String, String[]> paramMap = new HashMap<>(requestWrapper.getParameterMap());
        String paraValue; //参数值
        for (String paraName : paramMap.keySet()) {
            paraValue = request.getParameter(paraName);
            // 把原始参数值和经过滤的参数值进行对比，不相等则视为触发敏感词
            if (!paraValue.equals(SensitiveWord.filterStr(paraValue))) {
                // 判断采用何种处理方式
                if (isSilent) {
                    paramMap.put(paraName, new String[]{SensitiveWord.filterStr(paraValue)});
                    requestWrapper.setParameterMap(paramMap);
                    servletRequest = requestWrapper;
                } else {
                    log.error("请求参数包含敏感词：{}", paraValue);
                    Map<String, Object> map = new HashMap<>();
                    map.put("code", 40010);
                    map.put("msg", "请求参数包含敏感词汇！");
                    handleCustomException(servletResponse, JSON.toJSONString(map));
                    return;
                }
            }
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    /**
     * 自定义错误返回信息
     * @param servletResponse
     * @param errorMsg
     */
    private void handleCustomException(ServletResponse servletResponse, String errorMsg) {
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("application/json;charset=UTF-8");
        try (PrintWriter writer = servletResponse.getWriter()) {
            writer.print(errorMsg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
